package com.easylinkin.linkappapi.facerecognition.service.ai.impl;

import com.easylinkin.linkappapi.facerecognition.entity.FacePhoto;
import com.easylinkin.linkappapi.facerecognition.service.BaiduFaceAccessToken;
import com.easylinkin.linkappapi.facerecognition.service.FacePhotoService;
import com.easylinkin.linkappapi.facerecognition.service.ai.FaceRecognitionService;
import com.easylinkin.linkappapi.facerecognition.service.rest.BaiduManagementClientService;
import com.easylinkin.linkappapi.facerecognition.util.Base64Util;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import retrofit2.Call;
import retrofit2.Response;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;


/**
 * 百度平台的人脸识别能力
 * */
@Service
@ConditionalOnProperty(value = "ai.face.platform", havingValue = "baidu")
public class BaiduFaceRecognitionService implements FaceRecognitionService {

    private static  final Logger log = LoggerFactory.getLogger(BaiduFaceRecognitionService.class);

    @Autowired
    private BaiduManagementClientService baiduManagementClient;

    @Autowired
    private BaiduFaceAccessToken baiduFaceAccessToken;

    @Autowired
    private FacePhotoService facePhotoService;

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Value("${ai.face.baidu.group}")
    private String groupId;



    /**
     * 百度平台的用户ID使用 租户ID_username 组成
     * */
    @Override
    public Optional<JsonObject> registerUser(String username,  MultipartFile[] photos, List<String> faceTokens, Map<String, String> photoUrls) {
        String accessToken = baiduFaceAccessToken.accessToken();
        for (MultipartFile photo: photos) {
            Response<JsonObject> baiduResponse = null;
            try {
                String base64Img  = Base64Util.encode(photo.getBytes());
                JsonObject body = new JsonObject();
                body.addProperty("image", base64Img);
                body.addProperty("image_type", "BASE64");
                body.addProperty("group_id", groupId);
                body.addProperty("user_id", username);

                Call<JsonObject> jsonObjectCall = baiduManagementClient.facesetAdd(accessToken, body);
                baiduResponse = jsonObjectCall.execute();
                if (baiduRequestSuccess(baiduResponse)) {
                    String faceToken = baiduResponse.body().getAsJsonObject("result").get("face_token").getAsString();
                    FacePhoto facePhoto = new FacePhoto();
                    facePhoto.setPhotoId(faceToken);
                    facePhoto.setPhotoUrl(photoUrls.get(photo.getOriginalFilename()));
                    facePhotoService.save(facePhoto);
                } else {
                    return Optional.of(baiduResponse.body());
                }
            } catch (IOException e) {
                return Optional.of(baiduResponse.body());
            }
        }

        for (String token: faceTokens) {
            Response<JsonObject> baiduResponse = null;
            try {
                JsonObject body = new JsonObject();
                body.addProperty("image", token);
                body.addProperty("image_type", "FACE_TOKEN");
                body.addProperty("group_id", groupId);
                body.addProperty("user_id", username);

                Call<JsonObject> jsonObjectCall = baiduManagementClient.facesetAdd(accessToken, body);
                baiduResponse = jsonObjectCall.execute();
                if (baiduRequestSuccess(baiduResponse)) {

                } else {
                    return Optional.of(baiduResponse.body());
                }
            } catch (IOException e) {
                return Optional.of(baiduResponse.body());
            }
        }
        return Optional.empty();
    }

    @Override
    public Optional<JsonObject> updateUser(String username, String subjectId, String userId, MultipartFile[] photos, List<String> imgs, Map<String, String> photoUrls) {
        boolean deleteCurrentUser = deleteUser(subjectId);
        if (!deleteCurrentUser) {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("desc", "删除第三方平台用户失败");
            return Optional.of(jsonObject);
        }

        List<String> faceTokens = new ArrayList<String>();
        for (String img: imgs) {
            FacePhoto facePhoto = facePhotoService.queryPhotoWithUrl(img);
            if (facePhoto != null) {
                faceTokens.add(facePhoto.getPhotoId());
            }
        }

        return registerUser(linkappUserContextProducer.getCurrent().getTenantId() + "_" + username, photos, faceTokens, photoUrls);

    }

    @Override
    public boolean deleteUser(String subjectId) {
        String accessToken = baiduFaceAccessToken.accessToken();


        JsonObject body = new JsonObject();
        body.addProperty("group_id", groupId);
        body.addProperty("user_id", subjectId);
        Call<JsonObject> deleteCall = baiduManagementClient.deleteUser(accessToken, body);
        try {
            Response<JsonObject> deleteResponse = deleteCall.execute();
            if (baiduRequestSuccess(deleteResponse)) {
                return deleteResponse.body().get("error_code").getAsInt() == 0;
            }
        } catch (IOException e) {
            log.error("delete baidu user error, ", e);
        }
        return false;
    }

    @Override
    public Optional<JsonObject> recognize(File photoInfo) {
        String accessToken = baiduFaceAccessToken.accessToken();


        JsonObject body = new JsonObject();
        body.addProperty("group_id_list", groupId);
        body.addProperty("image_type", "BASE64");
        body.addProperty("image", Base64Util.encode(Base64Util.file2Byte(photoInfo)));
        Call<JsonObject> faceSearch = baiduManagementClient.faceSearch(accessToken, body);
        try {
            Response<JsonObject> faceSearchResponse = faceSearch.execute();
            if (baiduRequestSuccess(faceSearchResponse)) {
                return Optional.of(faceSearchResponse.body());
            }
        } catch (IOException e) {
            log.error("delete baidu user error, ", e);
        }
        return Optional.empty();
    }

    private boolean baiduRequestSuccess(Response<JsonObject> response) {

        if (response.isSuccessful()) {
            if (response.body() != null) {
                return response.body().get("error_code").getAsInt() == 0;
            }
        }

        return false;
    }
}
